/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.click.app.webapp.action;

import com.click.app.model.AsignationCutPay;
import com.click.app.model.BalanceEmployee;
import com.click.app.model.CutProcess;
import com.click.app.model.Employee;
import com.click.app.model.PaymentsCut;
import com.click.app.model.PeriodPaymentEmployee;
import com.click.app.service.AsignationCutPayManager;
import com.click.app.service.BalanceEmployeeManager;
import com.click.app.service.CutProcessManager;
import com.click.app.service.EmployeeManager;
import com.click.app.service.PaymentsCutManager;
import com.click.app.service.PeriodPaymentEmployeeManager;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author ariel
 */
public class PaymentsCutAction extends BaseAction {

    private PaymentsCutManager paymentsCutManager;
    private AsignationCutPayManager asignationCutPayManager;
    private EmployeeManager employeeManager;
    private CutProcessManager cutProcessManager;
    private BalanceEmployeeManager balanceEmployeeManager;
    private List<PaymentsCut> paymentsCuts;
    private List<BalanceEmployee> balances;
    private PaymentsCut paymentsCut;
    private Long id;
    private Employee employee;
    private Long idEmployee;
    private boolean editable;
    private Long lastBalanceId;
    private boolean canAdd;
    private List<CutProcess> cutProcesses;
    private Double availableAmount;
    private PeriodPaymentEmployee periodPaymentEmployee;
    private PeriodPaymentEmployeeManager periodPaymentEmployeeManager;

    public void setId(Long id) {
        this.id = id;
    }

    public void setIdEmployee(Long idEmployee) {
        this.idEmployee = idEmployee;
    }

    public PaymentsCut getPaymentsCut() {
        return paymentsCut;
    }

    public void setPaymentsCut(PaymentsCut paymentsCut) {
        this.paymentsCut = paymentsCut;
    }

    public Employee getEmployee() {
        return employee;
    }

    public boolean isEditable() {
        return editable;
    }

    public void setEditable(boolean editable) {
        this.editable = editable;
    }

    public Long getLastBalanceId() {
        return lastBalanceId;
    }

    public boolean isCanAdd() {
        return canAdd;
    }

    public List<CutProcess> getCutProcesses() {
        return cutProcesses;
    }

    public Double getAvailableAmount() {
//        if (paymentsCut.getId() != null) {
//            if(editable){
//                employee = (Employee) getSession().getAttribute("employee");
//                availableAmount = 0f;
//                List<AsignationCutPay> asignationCutPays = paymentsCutManager.get(paymentsCut.getId()).getAsignationCutPays();
//                for (AsignationCutPay a : asignationCutPays) {
//                    availableAmount = availableAmount + a.getAmountPayed();
//                }
//                List<CutProcess> cPs = cutProcessManager.findByEmployeePay(employee);
//                for(CutProcess cP : cPs){
//                    availableAmount = availableAmount + cP.getTotalCurrentAmount();
//                }
//            }
//        } else {
//            employee = (Employee) getSession().getAttribute("employee");
//            availableAmount = 0f;
//            List<CutProcess> cPs = cutProcessManager.findByEmployeePay(employee);
//            for(CutProcess cP : cPs){
//                availableAmount = availableAmount + cP.getTotalCurrentAmount();
//            }
//        }

        employee = (Employee) getSession().getAttribute("employee");

        periodPaymentEmployee = periodPaymentEmployeeManager.getCurrentPeriodByIdEmployeeAndRole(employee.getId(), employee.getRoleByName("ROLE_EMPLOYEE_CUTTER").getIdRole());
        return periodPaymentEmployee.getCurrentAmount();
    }

    public String generateCutProcessList() {
        System.out.println("generating cutProcessList...");
        if (editable) {
            employee = (Employee) getSession().getAttribute("employee");
            if (id == null) {
                cutProcesses = cutProcessManager.findByEmployeePay(employee);
            } else {
                PaymentsCut pC = paymentsCutManager.get(id);
                cutProcesses = new ArrayList<CutProcess>();
                for (AsignationCutPay aCP : pC.getAsignationCutPays()) {
                    CutProcess cP = new CutProcess(aCP.getCutProcess().getId(), aCP.getCutProcess().getInitDate(), aCP.getCutProcess().getTotalAmount(), aCP.getCutProcess().getTotalAmountFail(), aCP.getCutProcess().getTotalCurrentAmount(), aCP.getCutProcess().getEndDate());
                    cP.setTotalCurrentAmount(cP.getTotalCurrentAmount() + aCP.getAmountPayed());
                    cutProcesses.add(cP);
                }
                List<CutProcess> cutProcessList = cutProcessManager.findByEmployeePay(employee);
                if (cutProcessList.size() > 0 && cutProcessList.get(0).getId().equals(cutProcesses.get(cutProcesses.size() - 1).getId())) {
                    cutProcessList.remove(0);
                }
                cutProcesses.addAll(cutProcessList);
            }
        } else {
            PaymentsCut pC = paymentsCutManager.get(id);
            cutProcesses = new ArrayList<CutProcess>();
            for (AsignationCutPay aCP : pC.getAsignationCutPays()) {
                cutProcesses.add(aCP.getCutProcess());
            }
        }

        return SUCCESS;
    }

    public String delete() {
        System.out.println("PaymentsCutAction -> delete() " + id);
        if (id != null) {
            paymentsCut = paymentsCutManager.get(id);

            List<AsignationCutPay> asignationCutPays = asignationCutPayManager.findByPaymentsCut(paymentsCut);
            for (AsignationCutPay a : asignationCutPays) {
                a.getCutProcess().setTotalCurrentAmount(a.getCutProcess().getTotalCurrentAmount() + a.getAmountPayed());
                cutProcessManager.save(a.getCutProcess());
            }
            BalanceEmployee balanceEmployee = paymentsCut.getBalanceEmployee();
            PeriodPaymentEmployee perPayEmpl = balanceEmployee.getPeriodPaymentEmployee();
            perPayEmpl.setCurrentAmount(perPayEmpl.getCurrentAmount() + paymentsCut.getAmount());
            perPayEmpl.setAmountPayment(perPayEmpl.getAmountPayment() - paymentsCut.getAmount());
            periodPaymentEmployeeManager.save(perPayEmpl);

            //balanceEmployeeManager.remove(balanceEmployee.getId());

            paymentsCutManager.remove(paymentsCut.getId());
            saveMessage(getText("paymentsCut.deleted"));
        }
        System.out.println("PaymentsCutAction -> end delete() ");
        return SUCCESS;
    }

    public String edit() {
        if (id != null) {
            paymentsCut = paymentsCutManager.get(id);
            employee = (Employee) getSession().getAttribute("employee");
            if (balanceEmployeeManager.lastBalance(employee).getId().equals(paymentsCut.getBalanceEmployee().getId())) {
                setEditable(true);
            }
        } else {
            paymentsCut = new PaymentsCut();
            setEditable(true);
        }

        return SUCCESS;
    }

    public String save() throws Exception {
        System.out.println("PaymentsCutAction -> save() ");

        availableAmount = getAvailableAmount();
        if (paymentsCut.getAmount() <= 0 || paymentsCut.getAmount() > availableAmount) {
            errorMessage(getText("paymentsCut.amount") + " " + getText("errors.dynamicdoublerange") + " " + availableAmount + ".");
            return INPUT;
        }

        boolean isNew = (paymentsCut.getId() == null);

        employee = (Employee) getSession().getAttribute("employee");
        periodPaymentEmployee = periodPaymentEmployeeManager.getCurrentPeriodByIdEmployeeAndRole(employee.getId(), employee.getRoleByName("ROLE_EMPLOYEE_CUTTER").getIdRole());

        paymentsCut.setPeriodPaymentEmployee(periodPaymentEmployee);

        if (isNew) {
            paymentsCut = paymentsCutManager.save(paymentsCut);
            List<CutProcess> cutProcessList = cutProcessManager.findByEmployeePay(employee);
            Double cont = paymentsCut.getAmount();
            for (CutProcess cP : cutProcessList) {
                AsignationCutPay a = new AsignationCutPay();
                a.setCutProcess(cP);
                a.setPaymentsCut(paymentsCut);
                if (cP.getTotalCurrentAmount() < cont) {
                    a.setAmountPayed(cP.getTotalCurrentAmount());
                    asignationCutPayManager.save(a);
                    cont = cont - cP.getTotalCurrentAmount();
                    cP.setTotalCurrentAmount(0D);
                    cutProcessManager.save(cP);
                } else {
                    a.setAmountPayed(cont);
                    asignationCutPayManager.save(a);
                    cP.setTotalCurrentAmount(cP.getTotalCurrentAmount() - cont);
                    cutProcessManager.save(cP);
                    break;
                }
            }
            BalanceEmployee bE = new BalanceEmployee();
            bE.setPeriodPaymentEmployee(periodPaymentEmployee);
            bE.setPaymentsCut(paymentsCut);
            bE.setTypeBalance(3);
            bE.setObservation("PAGO NORMAL");
            bE.setAmountPaid(paymentsCut.getAmount());
            bE.setDateBalance(paymentsCut.getDatePay());
            bE.setBalance(periodPaymentEmployee.getCurrentAmount() - paymentsCut.getAmount());
            bE = balanceEmployeeManager.save(bE);

            periodPaymentEmployee.setCurrentAmount(periodPaymentEmployee.getCurrentAmount() - paymentsCut.getAmount());
            periodPaymentEmployee.setAmountPayment(periodPaymentEmployee.getAmountPayment() + paymentsCut.getAmount());
            periodPaymentEmployeeManager.save(periodPaymentEmployee);

        }
//            else {
//            PaymentsCut pC = paymentsCutManager.get(paymentsCut.getId());
//            System.out.println(paymentsCut.getAmount());
//            System.out.println(pC.getAmount());
//            if (paymentsCut.getAmount() < pC.getAmount()) {
//                Double dif = pC.getAmount() - paymentsCut.getAmount();
//                List<AsignationCutPay> aCPs = pC.getAsignationCutPays();
//                int size = aCPs.size();
//                while (dif > 0) {
//                    AsignationCutPay a = aCPs.get(size - 1);
//                    if (a.getCutProcess().getTotalAmount() > (a.getCutProcess().getTotalCurrentAmount() + dif)) {
//                        a.getCutProcess().setTotalCurrentAmount(a.getCutProcess().getTotalCurrentAmount() + dif);
//                        cutProcessManager.save(a.getCutProcess());
//                        a.setAmountPayed(a.getAmountPayed() - dif);
//                        asignationCutPayManager.save(a);
//                        break;
//                    }
//                    if (a.getCutProcess().getTotalAmount() == (a.getCutProcess().getTotalCurrentAmount() + dif)) {
//                        a.getCutProcess().setTotalCurrentAmount(a.getCutProcess().getTotalAmount());
//                        cutProcessManager.save(a.getCutProcess());
//                        asignationCutPayManager.remove(a.getId());
//                        break;
//                    }
//                    if (a.getCutProcess().getTotalAmount() < (a.getCutProcess().getTotalCurrentAmount() + dif)) {
//                        dif = dif - (a.getCutProcess().getTotalAmount() - a.getCutProcess().getTotalCurrentAmount());
//                        a.getCutProcess().setTotalCurrentAmount(a.getCutProcess().getTotalAmount());
//                        cutProcessManager.save(a.getCutProcess());
//                        asignationCutPayManager.remove(a.getId());
//                    }
//                    size--;
//                }
//            }
//            if (paymentsCut.getAmount() > pC.getAmount()) {
//                List<CutProcess> cutProcessList = cutProcessManager.findByEmployeePay(employee);
//                Double cont = paymentsCut.getAmount() - pC.getAmount();
//                for (CutProcess cP : cutProcessList) {
//                    if (!pC.getAsignationCutPays().get(pC.getAsignationCutPays().size() - 1).getCutProcess().getId().equals(cP.getId())) {
//                        AsignationCutPay a = new AsignationCutPay();
//                        a.setCutProcess(cP);
//                        a.setPaymentsCut(paymentsCut);
//                        if (cP.getTotalCurrentAmount() < cont) {
//                            a.setAmountPayed(cP.getTotalCurrentAmount());
//                            asignationCutPayManager.save(a);
//                            cont = cont - cP.getTotalCurrentAmount();
//                            cP.setTotalCurrentAmount(0f);
//                            cutProcessManager.save(cP);
//                        } else {
//                            a.setAmountPayed(cont);
//                            asignationCutPayManager.save(a);
//                            cP.setTotalCurrentAmount(cP.getTotalCurrentAmount() - cont);
//                            cutProcessManager.save(cP);
//                            break;
//                        }
//                    } else {
//                        AsignationCutPay a = pC.getAsignationCutPays().get(pC.getAsignationCutPays().size() - 1);
//                        if (cP.getTotalCurrentAmount() < cont) {
//                            a.setAmountPayed(a.getAmountPayed() + cP.getTotalCurrentAmount());
//                            asignationCutPayManager.save(a);
//                            cont = cont - cP.getTotalCurrentAmount();
//                            cP.setTotalCurrentAmount(0f);
//                            cutProcessManager.save(cP);
//                        } else {
//                            a.setAmountPayed(a.getAmountPayed() + cont);
//                            asignationCutPayManager.save(a);
//                            cP.setTotalCurrentAmount(cP.getTotalCurrentAmount() - cont);
//                            cutProcessManager.save(cP);
//                            break;
//                        }
//                    }
//                }
//            }
//            BalanceEmployee bE = balanceEmployeeManager.lastBalance(employee);
//            bE.setAmountPaid(paymentsCut.getAmount());
//            bE.setDateBalance(paymentsCut.getDatePay());
//            bE.setBalance(balanceEmployeeManager.beforeLastBalance(employee).getBalance() - paymentsCut.getAmount());
//            balanceEmployeeManager.save(bE);
//            paymentsCut = paymentsCutManager.save(paymentsCut);
//        }

        String key = (isNew) ? "paymentsCut.added" : "paymentsCut.updated";
        saveMessage(getText(key));
        System.out.println("PaymentsCutAction -> end save() ");
        return SUCCESS;
    }

    public String back() {
        getSession().removeAttribute("employee");
        return SUCCESS;
    }

    public void setPaymentsCutManager(PaymentsCutManager paymentsCutManager) {
        this.paymentsCutManager = paymentsCutManager;
    }

    public void setAsignationCutPayManager(AsignationCutPayManager asignationCutPayManager) {
        this.asignationCutPayManager = asignationCutPayManager;
    }

    public void setEmployeeManager(EmployeeManager employeeManager) {
        this.employeeManager = employeeManager;
    }

    public void setCutProcessManager(CutProcessManager cutProcessManager) {
        this.cutProcessManager = cutProcessManager;
    }

    public void setBalanceEmployeeManager(BalanceEmployeeManager balanceEmployeeManager) {
        this.balanceEmployeeManager = balanceEmployeeManager;
    }

    public List<PaymentsCut> getPaymentsCuts() {
        return paymentsCuts;
    }

    public List<BalanceEmployee> getBalances() {
        return balances;
    }

    public String list() {

        if (idEmployee != null) {
            employee = employeeManager.get(idEmployee);
            getSession().setAttribute("employee", getEmployee());
        } else {
            employee = (Employee) getSession().getAttribute("employee");
        }

        if (employee != null) {
            periodPaymentEmployee = periodPaymentEmployeeManager.getCurrentPeriodByIdEmployeeAndRole(employee.getId(), employee.getRoleByName("ROLE_EMPLOYEE_CUTTER").getIdRole());
            balances = periodPaymentEmployee.getBalanceEmployess();
            if (!balances.isEmpty()) {
                lastBalanceId = balances.get(balances.size() - 1).getId();
            } else {
                lastBalanceId = 0l;
            }
            List<CutProcess> cPs = cutProcessManager.findByEmployeePay(employee);
            if (cPs != null && cPs.size() > 0) {
                canAdd = true;
            }
            return SUCCESS;
        } else {
            System.out.println("employee is null: idEmployee = " + idEmployee);
            return ERROR;
        }
    }

    public String help() {
        return SUCCESS;
    }

    public String helpList() {
        return SUCCESS;
    }

    public PeriodPaymentEmployee getPeriodPaymentEmployee() {
        return periodPaymentEmployee;
    }

    public void setPeriodPaymentEmployee(PeriodPaymentEmployee periodPaymentEmployee) {
        this.periodPaymentEmployee = periodPaymentEmployee;
    }

    public PeriodPaymentEmployeeManager getPeriodPaymentEmployeeManager() {
        return periodPaymentEmployeeManager;
    }

    public void setPeriodPaymentEmployeeManager(PeriodPaymentEmployeeManager periodPaymentEmployeeManager) {
        this.periodPaymentEmployeeManager = periodPaymentEmployeeManager;
    }
}
